package com.mingxingyi.applet.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.mingxingyi.applet.constant.UserLoginConstant;
import com.mingxingyi.applet.mapper.UserFriendListMapper;
import com.mingxingyi.applet.mapper.UserInfoMapper;
import com.mingxingyi.applet.pojo.dto.UserFriendListDto;
import com.mingxingyi.applet.pojo.dto.UserInfoDto;
import com.mingxingyi.applet.pojo.dto.UserLoginDto;
import com.mingxingyi.applet.pojo.entity.UserFriendList;
import com.mingxingyi.applet.pojo.entity.UserInfo;
import com.mingxingyi.applet.pojo.vo.UserFriendListVo;
import com.mingxingyi.applet.pojo.vo.UserInfoVo;
import com.mingxingyi.applet.pojo.vo.UserLoginVo;
import com.mingxingyi.applet.service.UserInfoService;
import com.mingxingyi.applet.service.WechatService;
import com.mingxingyi.applet.utils.GeneralSn;
import com.mingxingyi.base.constant.ResultConstant;
import com.mingxingyi.base.context.AppletContext;
import com.mingxingyi.base.pojo.RequestDTO;
import com.mingxingyi.base.pojo.ResultVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class UserInfoServiceImpl implements UserInfoService {


    @Autowired
    private WechatService wechatService;
    @Resource
    private UserInfoMapper userInfoMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private UserFriendListMapper userFriendListMapper;

    public static final String FILE_PATH_ENV = "FILE_PATH";

    public static final String FILE_PATH_IMAGES = "/images/";

    public static final String FILE_RELATIVE_PATH_ENV = "FILE_RELATIVE_PATH";

    public static final int UPDATE_USER_STATUS_MAX_TIMES = 10;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVO<UserLoginVo> loginFirst(MultipartFile file,
                                            String username,
                                            String code,
                                            String phoneNumber) throws IOException {
        if (file == null
                || StringUtils.isBlank(code)
                || StringUtils.isBlank(phoneNumber)) {
            return ResultVO.fail("参数不能为空");
        }

        String path = this.saveImagesAndReturnPath(file);
        String openid = wechatService.getOpenid(code);
        ResultVO<UserLoginVo> voResultVO = new ResultVO<>();
        UserLoginVo userLoginVo = new UserLoginVo();
        voResultVO.setData(userLoginVo);

        LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserInfo::getOpenId, openid);
        wrapper.eq(UserInfo::getStatus, UserLoginConstant.DEFAULT_ZERO);
        UserInfo userInfo = userInfoMapper.selectOne(wrapper);
        if (Objects.nonNull(userInfo)) {
            //已有账号提示登录
            userLoginVo.setUsername(username);
            userLoginVo.setProfileImagePath(path);
            userLoginVo.setId(userInfo.getId());
            userLoginVo.setPhoneNumber(phoneNumber);
            voResultVO.setCode(ResultConstant._LOGIN_DIRECT);
            return voResultVO;
        }

        userInfo = new UserInfo();
        userInfo.setOpenId(openid);
        userInfo.setUsername(username);
        userInfo.setPhoneNumber(phoneNumber);
        userInfo.setProfileImagePath(path);
        userInfo.setCreateTime(new Date());
        userInfoMapper.insert(userInfo);
        Integer userId = userInfo.getId();
        String loginToken = this.getAndSaveAccessToken(userId);
        String refreshToken = this.getAndSaveRefreshToken(userId);


        userLoginVo.setId(userId);
        userLoginVo.setAccessToken(loginToken);
        userLoginVo.setRefreshToken(refreshToken);
        userLoginVo.setProfileImagePath(path);
        userLoginVo.setPhoneNumber(phoneNumber);
        userLoginVo.setUsername(username);
        userLoginVo.setNotificationSwitch(UserLoginConstant.DEFAULT_ONE);
        userLoginVo.setUserStatus(UserLoginConstant.DEFAULT_ZERO);
        return voResultVO;
    }

    @Override
    public ResultVO<UserLoginVo> login(RequestDTO<UserLoginDto> dto) {
        UserLoginDto data = dto.getData();
        Integer id = data.getId();
        String code = data.getCode();
        String openid = null;
        boolean isNotNull;
        if ((isNotNull = id != null && id > 0) || StringUtils.isNotBlank(code)) {
            LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
            // 点击登录之后，已有登录账号
            if (isNotNull) {
                wrapper.eq(UserInfo::getId, id);
            } else {
                //直接登录
                openid = wechatService.getOpenid(code);
                wrapper.eq(UserInfo::getOpenId, openid);
            }
            UserInfo userInfo = userInfoMapper.selectOne(wrapper);
            log.info("登录，：{},{},{}", id, code, JSONUtil.toJsonStr(userInfo));
            ResultVO<UserLoginVo> voResultVO = new ResultVO<>();
            UserLoginVo userLoginVo = new UserLoginVo();
            voResultVO.setData(userLoginVo);
            if (Objects.nonNull(userInfo)) {
                UserInfo updateUserInfo = new UserInfo();
                String profileImagePath = data.getProfileImagePath();
                String username = data.getUsername();
                String phoneNumber = data.getPhoneNumber();
                boolean update=false;
                if (update=StringUtils.isNotBlank(phoneNumber)) {
                    updateUserInfo.setPhoneNumber(phoneNumber);
                }
                if (update=StringUtils.isNotBlank(username)) {
                    updateUserInfo.setUsername(username);
                }
                if (update=StringUtils.isNotBlank(profileImagePath)) {
                    String storeProfileImagePath = userInfo.getProfileImagePath();
                    //如果有头像，并且前端没选头像，则不覆盖
                    if(StringUtils.isNotBlank(storeProfileImagePath)
                    && data.isDefaultImageFlag()){

                    }else {
                        updateUserInfo.setProfileImagePath(profileImagePath);
                    }
                }
                if (update &&Objects.nonNull(userInfo.getId())
                        && userInfo.getId() > 0) {
                    updateUserInfo.setId(userInfo.getId());
                    userInfoMapper.updateById(updateUserInfo);
                }
                userInfo = userInfoMapper.selectOne(wrapper);
                Integer userId = userInfo.getId();
                String loginToken = this.getAndSaveAccessToken(userId);
                String refreshToken = this.getAndSaveRefreshToken(userId);
                BeanUtils.copyProperties(userInfo, userLoginVo);
                userLoginVo.setAccessToken(loginToken);
                userLoginVo.setRefreshToken(refreshToken);
                return voResultVO;
            } else {
                userInfo = new UserInfo();
                userInfo.setUsername(StringUtils.isNotBlank(data.getUsername()) ? data.getUsername() : "");
                userInfo.setProfileImagePath(data.getProfileImagePath());
                userInfo.setPhoneNumber(data.getPhoneNumber());
                userInfo.setOpenId(openid);
                userInfo.setCreateTime(new Date());
                userInfoMapper.insert(userInfo);
                Integer userId = userInfo.getId();
                String loginToken = this.getAndSaveAccessToken(userId);
                String refreshToken = this.getAndSaveRefreshToken(userId);


                userLoginVo.setId(userId);
                userLoginVo.setAccessToken(loginToken);
                userLoginVo.setRefreshToken(refreshToken);
                userLoginVo.setNotificationSwitch(UserLoginConstant.DEFAULT_ONE);
                userLoginVo.setUserStatus(UserLoginConstant.DEFAULT_ZERO);
                return voResultVO;
            }
        }
        log.info("登录失败,{}", JSONUtil.toJsonStr(dto));
        return ResultVO.fail("登录失败");
    }


    @Override
    public ResultVO<UserInfoVo> updateUserInfo(RequestDTO<UserInfoDto> vo) {
        UserInfoDto data = vo.getData();
        String userStatusStr = data.getUserStatusStr();
        Integer id = data.getId();
        if (Objects.isNull(id) || id == 0) {
            return ResultVO.fail("参数不能为空");
        }
        boolean sendMessage = false;
        if (StringUtils.isNotBlank(userStatusStr)) {
            LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(UserInfo::getId, id);
            UserInfo userInfo = userInfoMapper.selectOne(wrapper);
            //状态发生了改变，通知？
            if (userInfo != null && !userStatusStr.equals(userInfo.getUserStatusStr())) {
                String statusUpdateTimes = userInfo.getStatusUpdateTimes();
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                String format = simpleDateFormat.format(new Date());
                if (StringUtils.isNotBlank(statusUpdateTimes)) {
                    String[] split = statusUpdateTimes.split(UserLoginConstant.UNDERLINE);
                    String date = split[0];
                    String times = split[1];
                    if (date.equals(format)) {
                        int iTimes = Integer.parseInt(times);
                        if (iTimes >= UPDATE_USER_STATUS_MAX_TIMES) {
//                            UserInfoVo userInfoVo = new UserInfoVo();
//                            userInfoVo.setMaxUpdateTimes(UPDATE_USER_STATUS_MAX_TIMES);
//                            return ResultVO.fail(ResultConstant._UPDATE_USER_STATUS_MORE_TIMES, "", userInfoVo);
                        } else {
                            data.setStatusUpdateTimes(format + UserLoginConstant.UNDERLINE + (iTimes + 1));
                        }
                    } else {
                        data.setStatusUpdateTimes(format + UserLoginConstant.UNDERLINE + UserLoginConstant.DEFAULT_ONE);
                    }
                } else {
                    data.setStatusUpdateTimes(format + UserLoginConstant.UNDERLINE + UserLoginConstant.DEFAULT_ONE);
                }
                data.setLastUpdateTime(new Date());
                sendMessage = true;
            }
        }
        data.setCreateTime(null);
        data.setUpdateTime(new Date());
        data.setOpenId(null);
        int update = userInfoMapper.updateById(data);
        if (update <= 0) {
            return ResultVO.fail("操作失败");
        }
        if (sendMessage) {
            //状态通知
            CompletableFuture.runAsync(() -> {
                this.sendStatusChangeMessage(id);
            });
        }
        return ResultVO.success();
    }

    private void sendStatusChangeMessage(Integer id) {
        LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserInfo::getId, id);
        UserInfo userInfo = userInfoMapper.selectOne(wrapper);

        UserInfoVo userInfoVo = new UserInfoVo();
        userInfoVo.setId(id);
        List<UserInfoVo> userInfoVos = userInfoMapper.selectFriendList(userInfoVo);
        log.info("发送消息查询的通知列表：" + JSONUtil.toJsonStr(userInfoVos));
        for (UserInfoVo infoVo : userInfoVos) {
            Map<String, String> data = new HashMap<>();
            data.put("touser", infoVo.getOpenId());
            data.put("username", userInfo.getUsername());
            data.put("user_status_str", userInfo.getUserStatusStr());
            try {
                wechatService.sendMessage(data);
            }catch (Exception e){
                log.error("发送消息异常:",e);
            }
        }

    }

    @Override
    public ResultVO<UserInfoVo> uploadProfileImage(MultipartFile file, Integer userId) throws IOException {
        if (file != null) {
            if (Objects.isNull(userId) || userId == 0) {
                return ResultVO.fail("参数不能为空");
            }
            UserInfoDto data = new UserInfoDto();
            data.setId(userId);
            data.setUpdateTime(new Date());
            //转换成相对路径
            String path = this.saveImagesAndReturnPath(file);
            data.setProfileImagePath(path);
            int i = userInfoMapper.updateById(data);
            if (i > 0) {
                ResultVO<UserInfoVo> resultVO = new ResultVO<>();
                UserInfoVo userInfoVo = new UserInfoVo();
                resultVO.setData(userInfoVo);
                userInfoVo.setProfileImagePath(path);
                return resultVO;
            }
        }
        return ResultVO.fail("上传失败");
    }

    private String saveImagesAndReturnPath(MultipartFile file) throws IOException {
        String property = System.getProperty(FILE_PATH_ENV);
        //获取原始文件名
        String originalFilename = file.getOriginalFilename();
        originalFilename = System.currentTimeMillis() + originalFilename;
        String filePath = property + FILE_PATH_IMAGES;
        File dir = new File(filePath);
        if (!dir.exists()) {
            dir.mkdir();
        }
        String path = filePath + originalFilename;
        //将文件存储在服务器的磁盘目录
        file.transferTo(new File(path));
        path = FILE_PATH_IMAGES + originalFilename;
        return path;
    }

    @Override
    public ResultVO<UserInfoVo> getUserInfoOnFree(RequestDTO<UserInfoDto> vo) {
        UserInfoDto data = vo.getData();
        Integer userId = data.getId();
        String code = data.getCode();
        if (Objects.isNull(userId) || userId == 0
                || StringUtils.isBlank(code)) {
            return ResultVO.fail("参数不能为空");
        }
        String key = UserLoginConstant.WX_SHARE_TOKEN_REDIS_NAME + userId + code;
        log.info("效验key:{}", key);
        Boolean aBoolean = stringRedisTemplate.hasKey(key);
        if (aBoolean != null && aBoolean) {
            ResultVO<UserInfoVo> resultVO = new ResultVO<>();
            UserInfoVo userInfoVo = new UserInfoVo();
            resultVO.setData(userInfoVo);
            UserInfo userInfo = userInfoMapper.selectById(userId);
            if (Objects.nonNull(userInfo)) {
                String profileImagePath = userInfo.getProfileImagePath();
                userInfoVo.setProfileImagePath(profileImagePath);
                userInfoVo.setUsername(userInfo.getUsername());
                return resultVO;
            }
        }
        return ResultVO.fail("无效分享");
    }

    @Override
    public ResultVO<Object> getShareUid(RequestDTO<UserInfoDto> vo) {
        UserInfoDto data = vo.getData();
        Integer userId = data.getId();
        String code = data.getCode();
        log.info("code:{}", code);
        if (Objects.isNull(userId) || userId == 0 || StringUtils.isBlank(code)) {
            return ResultVO.fail("参数不能为空");
        }
        UserInfo userInfo = userInfoMapper.selectById(userId);
        if (Objects.nonNull(userInfo)) {
            String key = UserLoginConstant.WX_SHARE_TOKEN_REDIS_NAME + userId + code;
            log.info("创建key:{}", key);
            stringRedisTemplate.opsForValue().set(key,
                    "", 1, TimeUnit.DAYS);
            return ResultVO.success();
        }
        return ResultVO.fail("异常");
    }

    @Override
    public ResultVO<UserFriendListVo> addFriend(RequestDTO<UserFriendListDto> vo) {
        UserFriendListDto data = vo.getData();
        Integer userId = data.getUserId();
        Integer friendId = data.getFriendId();
        if (Objects.nonNull(userId) && userId > 0
                && Objects.nonNull(friendId) && friendId > 0) {
            if (userId.equals(friendId)) {
                return ResultVO.fail("不能添加自己");
            }
            LambdaQueryWrapper<UserInfo> userInfoQueryWrapper = new LambdaQueryWrapper<>();
            userInfoQueryWrapper.in(UserInfo::getId, Arrays.asList(userId, friendId));
            userInfoQueryWrapper.eq(UserInfo::getStatus, UserLoginConstant.DEFAULT_ZERO);
            List<UserInfo> userInfos = userInfoMapper.selectList(userInfoQueryWrapper);
            if (CollectionUtil.isEmpty(userInfos)) {
                return ResultVO.fail("用户名无效");
            }
            String str = "";
            if (userInfos.size() != 2) {
                Integer id = userInfos.get(0).getId();
                if (!id.equals(userId)) {
                    str = "添加人无效";
                } else {
                    str = "被添加人无效";
                }
                return ResultVO.fail(str);
            }
            LambdaQueryWrapper<UserFriendList> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(UserFriendList::getUserId, userId);
            queryWrapper.eq(UserFriendList::getFriendId, friendId);
            queryWrapper.eq(UserFriendList::getStatus, UserLoginConstant.DEFAULT_ZERO);
            UserFriendList userFriendList = userFriendListMapper.selectOne(queryWrapper);
            if (Objects.nonNull(userFriendList)) {
                return ResultVO.fail("不能重复添加");
            }

            queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(UserFriendList::getUserId, friendId);
            queryWrapper.eq(UserFriendList::getFriendId, userId);
            queryWrapper.eq(UserFriendList::getStatus, UserLoginConstant.DEFAULT_ZERO);
             userFriendList = userFriendListMapper.selectOne(queryWrapper);
            if (Objects.nonNull(userFriendList)) {
                return ResultVO.fail("不能重复添加");
            }
            userFriendList = new UserFriendList();
            userFriendList.setUserId(userId);
            userFriendList.setFriendId(friendId);
            userFriendList.setCreateTime(new Date());
            userFriendListMapper.insert(userFriendList);
            return ResultVO.success();
        }
        return ResultVO.fail("添加失败");
    }

    @Override
    public ResultVO<UserInfoVo> selectFriendList(RequestDTO<UserInfoVo> vo) {
        UserInfoVo data = vo.getData();
        Integer userId = data.getId();
        if (Objects.isNull(userId) || userId == 0) {
            return ResultVO.fail("参数不能为空");
        }

        List<UserInfoVo> userInfoVos = userInfoMapper.selectFriendList(data);
        //这里返回的Id为 UserFriendList的 主键
        if (CollectionUtil.isNotEmpty(userInfoVos)) {
            for (UserInfo userInfoVo : userInfoVos) {
                userInfoVo.setOpenId(null);
            }
        }
        return ResultVO.success(userInfoVos);
    }

    @Override
    public ResultVO<UserFriendListVo> updateRemark(RequestDTO<UserFriendListDto> dto) {
        UserFriendListDto data = dto.getData();
        Integer id = AppletContext.getCurrentUserId();
        String remark = data.getRemark();
        Integer friendId = data.getFriendId();
        Integer userId = data.getUserId();

        if (Objects.isNull(friendId) || friendId == 0
                || Objects.isNull(userId) || userId == 0
                || Objects.isNull(id) || id == 0
                || StringUtils.isBlank(remark)) {
            return ResultVO.fail("参数不能为空");
        }
        UserFriendList userFriendList = new UserFriendList();
        if (id.equals(userId)) {
            userFriendList.setFriendRemark(remark);
        } else {
            userFriendList.setRemark(remark);
        }
        LambdaUpdateWrapper<UserFriendList> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(UserFriendList::getFriendId, friendId)
                .eq(UserFriendList::getUserId, userId);
        int update = userFriendListMapper.update(userFriendList, updateWrapper);
        if (update <= 0) {
            return ResultVO.fail("操作失败");
        }

        return ResultVO.success();
    }

    @Override
    public ResultVO<UserFriendListVo> deleteFriend(RequestDTO<UserFriendListDto> vo) {
        UserFriendListDto data = vo.getData();

        Integer friendId = data.getFriendId();
        Integer userId = data.getUserId();

        if (Objects.isNull(friendId) || friendId == 0
                || Objects.isNull(userId) || userId == 0) {
            return ResultVO.fail("参数不能为空");
        }
        UserFriendList userFriendList = new UserFriendList();

        userFriendList.setStatus(UserLoginConstant.DEFAULT_ONE);

        LambdaUpdateWrapper<UserFriendList> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(UserFriendList::getFriendId, friendId)
                .eq(UserFriendList::getUserId, userId);
        int update = userFriendListMapper.update(userFriendList, updateWrapper);
        if (update <= 0) {
            return ResultVO.fail("操作失败");
        }

        return ResultVO.success();
    }

    @Override
    public ResultVO<UserLoginVo> loginOut(RequestDTO<UserLoginDto> vo) {
        UserLoginDto data = vo.getData();
        Integer userId = data.getId();
        if (userId == null || userId == 0) {
            return ResultVO.fail("参数不能为空");
        }
        AppletContext.removeCurrentUserId();
        this.deleteToken(userId);
        return ResultVO.success();
    }

    @Override
    public ResultVO<UserInfoVo> refreshToken(RequestDTO<UserInfoDto> vo) {
        UserInfoDto data = vo.getData();
        Integer userId = data.getId();
        if (userId == null || userId == 0) {
            return ResultVO.fail("参数不能为空");
        }
        String refreshToken = data.getRefreshToken();
        if (StringUtils.isBlank(refreshToken)) {
            return ResultVO.fail("参数不能为空");
        }
        ValueOperations<String, String> stringStringValueOperations = stringRedisTemplate.opsForValue();
        String refreshKey = UserLoginConstant.WX_REFRESH_TOKEN_REDIS_KEY + UserLoginConstant.STRIKE + userId;
        String storeRefreshToken = stringStringValueOperations.get(refreshKey);
        if (StringUtils.isNotBlank(storeRefreshToken)
                && refreshToken.equals(storeRefreshToken)) {
            String accessKey = UserLoginConstant.WX_ACCESS_TOKEN_REDIS_KEY + UserLoginConstant.STRIKE + userId;

            String originAccessToken = stringStringValueOperations.get(accessKey);
            if (StringUtils.isNotBlank(originAccessToken)) {
                //保存之前的token
                this.setTemporaryAccessToken(originAccessToken, userId);
                String loginToken = this.getAndSaveAccessToken(userId);
                refreshToken = this.getAndSaveRefreshToken(userId);
                ResultVO<UserInfoVo> resultVO = new ResultVO<>();
                UserInfoVo infoVo = new UserInfoVo();
                resultVO.setData(infoVo);
                infoVo.setRefreshToken(refreshToken);
                infoVo.setAccessToken(loginToken);
                return resultVO;
            }
        }
        return ResultVO.fail(ResultConstant._LOGIN_ERROR, "登录异常");
    }

    @Override
    public ResultVO<UserInfoVo> getPhoneNumber(RequestDTO<UserInfoVo> vo) {
        UserInfoVo data = vo.getData();
        Integer userId = data.getId();
        String code = data.getCode();
        if (userId == null || userId == 0
                || StringUtils.isBlank(code)) {
            return ResultVO.fail("参数不能为空");
        }
        UserInfo userInfo = userInfoMapper.selectById(userId);
        if (Objects.isNull(userInfo)) {
            return ResultVO.fail("用户不存在");
        }

        ResultVO<UserInfoVo> resultVO = new ResultVO<>();
        UserInfoVo userInfoVo = new UserInfoVo();
        resultVO.setData(userInfoVo);
        String phone = wechatService.getPhone(code);
        if (StringUtils.isNotBlank(phone)) {
            userInfoVo.setPhoneNumber(phone);

            UserInfo updateUserInfo = new UserInfo();
            updateUserInfo.setId(userInfo.getId());
            updateUserInfo.setPhoneNumber(phone);
            userInfoMapper.updateById(updateUserInfo);
        } else {
            userInfoVo.setPhoneNumber("");
        }
        return resultVO;
    }

    @Override
    public ResultVO<UserInfoVo> getPhoneNumberFree(RequestDTO<UserInfoVo> vo) {
        UserInfoVo data = vo.getData();
        String code = data.getCode();
        if (StringUtils.isBlank(code)) {
            return ResultVO.fail("参数不能为空");
        }
        ResultVO<UserInfoVo> resultVO = new ResultVO<>();
        UserInfoVo userInfoVo = new UserInfoVo();
        resultVO.setData(userInfoVo);
        String phone = wechatService.getPhone(code);
        userInfoVo.setPhoneNumber(phone);
        return resultVO;
    }


    /**
     * 刷新token 平滑处理
     *
     * @param originAccessToken
     * @param userId
     */
    public void setTemporaryAccessToken(String originAccessToken, Integer userId) {
        ValueOperations<String, String> stringStringValueOperations = stringRedisTemplate.opsForValue();
        stringStringValueOperations.set(
                UserLoginConstant.WX_ACCESS_TOKEN_TEMPORARY_REDIS_KEY + UserLoginConstant.STRIKE + userId,
                originAccessToken,
                UserLoginConstant.ACCESS_TOKEN_TEMPORARY_STORE_TIME,
                TimeUnit.MINUTES
        );
    }

    public String getAndSaveAccessToken(Integer userId) {
        String loginToken = GeneralSn.getLoginToken();
        ValueOperations<String, String> stringStringValueOperations = stringRedisTemplate.opsForValue();
        stringStringValueOperations.set(
                UserLoginConstant.WX_ACCESS_TOKEN_REDIS_KEY + UserLoginConstant.STRIKE + userId,
                loginToken,
                UserLoginConstant.ACCESS_TOKEN_STORE_TIME,
                TimeUnit.HOURS
        );
        return loginToken;
    }

    public String getAndSaveRefreshToken(Integer userId) {
        String refreshToken = GeneralSn.getRefreshToken();
        ValueOperations<String, String> stringStringValueOperations = stringRedisTemplate.opsForValue();
        stringStringValueOperations.set(
                UserLoginConstant.WX_REFRESH_TOKEN_REDIS_KEY + UserLoginConstant.STRIKE + userId,
                refreshToken,
                UserLoginConstant.REFRESH_STORE_TIME,
                TimeUnit.HOURS
        );
        return refreshToken;
    }

    public void deleteToken(Integer userId) {
        stringRedisTemplate.delete(UserLoginConstant.WX_REFRESH_TOKEN_REDIS_KEY + UserLoginConstant.STRIKE + userId);

        stringRedisTemplate.delete(UserLoginConstant.WX_ACCESS_TOKEN_REDIS_KEY + UserLoginConstant.STRIKE + userId);

        stringRedisTemplate.delete(UserLoginConstant.WX_ACCESS_TOKEN_TEMPORARY_REDIS_KEY + UserLoginConstant.STRIKE + userId);

    }
}
